package com.ktgj.flight.service.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
import com.ktgj.common.core.text.Convert;
import com.ktgj.common.core.utils.DateCalcUtils;
import com.ktgj.common.core.utils.DateUtils;
import com.ktgj.common.core.utils.helper.StringHelper;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ktgj.flight.mapper.FlightOrderCabinruleMapper;
import com.ktgj.flight.domain.FlightOrderCabinrule;
import com.ktgj.flight.service.IFlightOrderCabinruleService;

/**
 * 每个订单的退改签信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-10-26
 */
@Service
public class FlightOrderCabinruleServiceImpl implements IFlightOrderCabinruleService 
{
    @Autowired
    private FlightOrderCabinruleMapper flightOrderCabinruleMapper;

    /**
     * 查询每个订单的退改签信息
     * 
     * @param orderCabinruleId 每个订单的退改签信息ID
     * @return 每个订单的退改签信息
     */
    @Override
    public FlightOrderCabinrule selectFlightOrderCabinruleById(Long orderCabinruleId)
    {
        return flightOrderCabinruleMapper.selectFlightOrderCabinruleById(orderCabinruleId);
    }

    /**
     * 查询每个订单的退改签信息列表
     * 
     * @param flightOrderCabinrule 每个订单的退改签信息
     * @return 每个订单的退改签信息
     */
    @Override
    public List<FlightOrderCabinrule> selectFlightOrderCabinruleList(FlightOrderCabinrule flightOrderCabinrule)
    {
        return flightOrderCabinruleMapper.selectFlightOrderCabinruleList(flightOrderCabinrule);
    }

    /**
     * 新增每个订单的退改签信息
     * 
     * @param flightOrderCabinrule 每个订单的退改签信息
     * @return 结果
     */
    @Override
    public int insertFlightOrderCabinrule(FlightOrderCabinrule flightOrderCabinrule)
    {
        flightOrderCabinrule.setCreateTime(DateUtils.getNowDate());
        return flightOrderCabinruleMapper.insertFlightOrderCabinrule(flightOrderCabinrule);
    }

    /**
     * 修改每个订单的退改签信息
     * 
     * @param flightOrderCabinrule 每个订单的退改签信息
     * @return 结果
     */
    @Override
    public int updateFlightOrderCabinrule(FlightOrderCabinrule flightOrderCabinrule)
    {
        return flightOrderCabinruleMapper.updateFlightOrderCabinrule(flightOrderCabinrule);
    }

    /**
     * 批量删除每个订单的退改签信息
     * 
     * @param orderCabinruleIds 需要删除的每个订单的退改签信息ID
     * @return 结果
     */
    @Override
    public int deleteFlightOrderCabinruleByIds(Long[] orderCabinruleIds)
    {
        return flightOrderCabinruleMapper.deleteFlightOrderCabinruleByIds(orderCabinruleIds);
    }

    /**
     * 删除每个订单的退改签信息信息
     * 
     * @param orderCabinruleId 每个订单的退改签信息ID
     * @return 结果
     */
    @Override
    public int deleteFlightOrderCabinruleById(Long orderCabinruleId)
    {
        return flightOrderCabinruleMapper.deleteFlightOrderCabinruleById(orderCabinruleId);
    }


    /// <summary>
    /// 起飞前计算
    /// </summary>
    /// <param name="nowtime"></param>
    /// <param name="deptime"></param>
    /// <param name="conDesc"></param>
    /// <param name="baseAmount"></param>
    /// <returns></returns>
    private double _GetFee(Date nowtime, Date deptime, String conDesc, double baseAmount)
    {
        //起飞前退改签规则（期限|单位|数值|百分比^期限|单位|数值|百分比~期限|单位|数值|期限|单位|数值|百分比）

        //期限：0（不限制）,1(以前)，2（以内），3（以后）
        //单位：0（不限制）,1（小时）,2（天）,3（周）,4(月),5（年）
        //数值：0（不限制），1,2,3,4,5,6,7....

        double fee = -1;
        String[] strA = conDesc.split("~");
        for (String strB : strA)
        {
            for (String strCon : strB.split("^"))
            {
                if (fee > 0) break;

                String[] strC3 = strCon.split("|");
                if (strC3.length == 7)//期限|单位|数值|期限|单位|数值|百分比 ,大条件需要重新构造成小条件
                {
                    //需要计算出两个时间
                    String[] strC0 = Convert.toStr(strC3[0] + "|" + strC3[1] + "|" + strC3[2] + "|" + strC3[6]).split("|");

                    String[] strC1 = Convert.toStr(strC3[3] + "|" + strC3[4] + "|" + strC3[5] + "|" + strC3[6]).split("|");

                    //如果匹配，则计算退票费
                    if (_isFitTime(nowtime, deptime, strC0) && _isFitTime(nowtime, deptime, strC1))
                    {
                        BigDecimal percent = new BigDecimal(strC3[6]);
                        fee = Math.round((baseAmount * (percent.doubleValue() / 100)) + 0.499);
                    }
                }
                else if (strC3.length > 0)//期限|单位|数值|百分比，小条件直接计算
                {
                    //如果有条件1和条件2
                    if (strB.length() > 1)
                    {
                        BigDecimal percent = new BigDecimal(-1);
                        //如果匹配，则计算退票费
                        if (_isFitTime(nowtime, deptime, strC3))
                        {
                            percent = new BigDecimal(strC3[3]);
                            fee = Math.round((baseAmount * (percent.doubleValue() / 100)) + 0.499);
                        }
                    }

                }
            }
        }
        return fee;
    }

    private double _GetFee(Date nowtime, Date deptime, String conDesc, double baseAmount, int times)
    {
        //起飞前退改签规则（期限|单位|数值|百分比|次数^期限|单位|数值|百分比|次数~期限|单位|数值|期限|单位|数值|百分比|次数）

        //期限：0（不限制）,1(以前)，2（以内），3（以后）
        //单位：0（不限制）,1（小时）,2（天）,3（周）,4(月),5（年）
        //数值：0（不限制），1,2,3,4,5,6,7....

        double fee = -1;

        String[] strA = conDesc.split("~");
        //如果有条件3
        if (strA.length > 1)
        {
            //region 计算退票费
            String[] strC3 = strA[1].split("|");
            if (strC3.length > 6)
            {
                //需要计算出两个时间
                String[] strC0 = Convert.toStr(strC3[0] + "|" + strC3[1] + "|" + strC3[2] + "|" + strC3[6]).split("|");

                String[] strC1 = Convert.toStr(strC3[3] + "|" + strC3[4] + "|" + strC3[5] + "|" + strC3[6]).split("|");


                //如果匹配，则计算退票费
                if (_isFitTime(nowtime, deptime, strC0) && _isFitTime(nowtime, deptime, strC1))
                {
                    BigDecimal percent = new BigDecimal(strC3[6]);
                    switch (strC3.length)
                    {
                        case 8:
                        {
                            int ruleTimes = Integer.parseInt(strC3[7]);
                            percent = ruleTimes > times ? new BigDecimal(0) : percent;
                        }
                        break;
                    }
                    fee = Math.round((baseAmount * (percent.doubleValue() / 100)) + 0.499);
                }
            }
            //endregion

        }
        //如果（没有条件3,或者有条件3但是没有计算出退票费）则计算：条件1和条件2
        if (fee < 0)
        {
            String[] strB = strA[0].split("^");

            //region 计算退票费
            //如果有条件1和条件2
            if (strB.length > 1)
            {
                String[] strC0 = strB[0].split("|");
                String[] strC1 = strB[1].split("|");
                BigDecimal percent = new BigDecimal(-1);
                //如果匹配，则计算退票费
                if (_isFitTime(nowtime, deptime, strC0))
                {
                    percent = new BigDecimal(strC0[3]);
                    switch (strC0.length)
                    {
                        case 5:
                        {
                            int ruleTimes = Integer.parseInt(strC0[4]);
                            percent = ruleTimes > times ? new BigDecimal(0) : percent;
                        }
                        break;
                    }
                }

                //如果条件0未计算出退票费，则尝试匹配条件1
                if (_isFitTime(nowtime, deptime, strC1))
                {
                    percent = new BigDecimal(strC1[3]);
                    switch (strC1.length)
                    {
                        case 5:
                        {
                            int ruleTimes = Integer.parseInt(strC1[4]);
                            percent = ruleTimes > times ? new BigDecimal(0) : percent;
                        }
                        break;
                    }
                }
                //如果百分比大于0，则计算退票费
                if (percent.doubleValue() >= 0)
                {
                    fee = Math.round((baseAmount * (percent.doubleValue() / 100)) + 0.499);
                }
            }
                //endregion
                //region 计算退票费
            //如果只有条件1
                else
            {

                String[] strC0 = strB[0].split("|");

                //如果匹配，则计算退票费
                if (_isFitTime(nowtime, deptime, strC0))
                {
                    BigDecimal percent = new BigDecimal(strC0[3]);
                    switch (strC0.length)
                    {
                        case 5:
                        {
                            int ruleTimes = Integer.parseInt(strC0[4]);
                            percent = ruleTimes > times ? new BigDecimal(0) : percent;
                        }
                        break;
                    }
                    fee = Math.round((baseAmount * (percent.doubleValue() / 100) + 0.499));
                }

            }
            //endregion
        }

        return fee;
    }

    /**
     * 判断是否为正确的时间
     */
    private boolean _isFitTime(Date nowtime, Date deptime, String[] strC)
    {
        //如果为起飞前，起飞时间

        boolean isfit = false;
            //region 计算退票费
        //如果只有条件1

        if (strC.length > 3)
        {
            int nType = Integer.parseInt(strC[0]);
            int nUnit = Integer.parseInt(strC[1]);
            int nValue = Integer.parseInt(strC[2]);
            String strPercent = strC[3];
            //首先判断百分比不为空，则需要计算退票手续费
            if (!StringHelper.isNullOrEmpty(strPercent))
            {
                //将最后的条件都转化为小时
                //首先默认为-1
                int TotalHour = -1;

                //期限：0（不限制）,1(以前)，2（以内），3（以后）
                //单位：0（不限制）,1（小时）,2（天）,3（周）,4(月),5（年）
                //数值：0（不限制），1,2,3,4,5,6,7....

                    //region 将条件转化为小时

                if (nUnit == 0)
                {
                    TotalHour = 0;
                }
                else if (nUnit == 1)
                {
                    TotalHour = nValue;
                }
                else if (nUnit == 2)
                {
                    TotalHour = 24 * nValue;
                }
                else if (nUnit == 3)
                {
                    TotalHour = 7 * 24 * nValue;
                }
                //如果是月份则以30天为单位
                else if (nUnit == 4)
                {
                    TotalHour = 30 * 7 * 24 * nValue;
                }
                else if (nUnit == 5)
                {
                    TotalHour = 365 * 30 * 7 * 24 * nValue;
                }
                    //endregion
                //起飞时间减去小时数，得到一个新的时间与当前时间作对比
                //如果为起飞前：新时间需要减去小时数
                boolean isQian = false;
                if (nowtime.getTime() < deptime.getTime())
                {
                    isQian = true;
                    TotalHour = TotalHour * -1;
                }
                Date depTypeTime = new Date();
                DateCalcUtils.addHour(depTypeTime,TotalHour);

                //如果不限制
                if (nType == 0)
                {
                    //例：起飞前2小时(以前，以内，以后均可，此时与小时数无关，直接匹配)
                    isfit = true; //可以直接匹配
                }
                //以前
                else if (nType == 1)
                {

                    //可以匹配 例：起飞前2小时以前   当前时间为7点，航班起飞时间为10点，则有 7<8&&7<10
                    if (isQian)
                    {
                        if (nowtime.getTime() < depTypeTime.getTime() && nowtime.getTime() < deptime.getTime())
                        {
                            isfit = true;
                        }
                    }
                    //例起飞后两小时以前    当前时间为7点   6点起飞    则有 7<8&&7>6
                    else
                    {
                        if (nowtime.getTime() < depTypeTime.getTime() && nowtime.getTime() > deptime.getTime())
                        {
                            isfit = true;
                        }
                    }
                }
                //以内
                else if (nType == 2)
                {
                    //可以匹配 例：起飞前2小时以内   当前时间为9点，航班起飞时间为10点，则有 8<9&&9<10
                    if (isQian)
                    {
                        if (depTypeTime.getTime() <= nowtime.getTime() && nowtime.getTime() <= deptime.getTime())
                        {
                            isfit = true;
                        }
                    }
                    //例起飞后两小时以内    当前时间为7点   6点起飞    则有 7<8&&7>6
                    else
                    {
                        if (nowtime.getTime() <= depTypeTime.getTime() && nowtime.getTime() >= deptime.getTime())
                        {
                            isfit = true;
                        }
                    }
                }
                //以后
                else if (nType == 3)
                {
                    //可以匹配 例：起飞前2小时以后   当前时间为9点，航班起飞时间为10点，则有 8<9
                    if (isQian)
                    {
                        if (depTypeTime.getTime() < nowtime.getTime())
                        {
                            isfit = true;
                        }
                    }
                    //例起飞后两小时以后    当前时间为8点01分   6点起飞    则有8<8点01
                    else
                    {
                        if (depTypeTime.getTime() < nowtime.getTime())
                        {
                            isfit = true;
                        }
                    }
                }

            }
        }
            //endregion
        return isfit;
    }
}
